enum {
PROP_INSPECTED = 1,
+ PROP_RESIZE,
PROP_MAGNIFICATION
};
gdouble magnification;
gint x;
gint y;
+ gboolean resize;
+ gulong draw_handler;
+ gulong resize_handler;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkMagnifier, _gtk_magnifier,
_gtk_magnifier_set_magnification (GTK_MAGNIFIER (object),
g_value_get_double (value));
break;
+ case PROP_RESIZE:
+ _gtk_magnifier_set_resize (GTK_MAGNIFIER (object),
+ g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
}
case PROP_MAGNIFICATION:
g_value_set_double (value, priv->magnification);
break;
+ case PROP_RESIZE:
+ g_value_set_boolean (value, priv->resize);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
}
magnifier = GTK_MAGNIFIER (widget);
priv = _gtk_magnifier_get_instance_private (magnifier);
+ if (priv->inspected == NULL)
+ return FALSE;
+
if (!gtk_widget_is_visible (priv->inspected))
return FALSE;
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_get_allocation (priv->inspected, &inspected_alloc);
- cairo_translate (cr, allocation.width / 2, allocation.height / 2);
+
+ if (!priv->resize)
+ cairo_translate (cr, allocation.width / 2, allocation.height / 2);
x = CLAMP (priv->x, 0, inspected_alloc.width);
y = CLAMP (priv->y, 0, inspected_alloc.height);
cairo_save (cr);
cairo_scale (cr, priv->magnification, priv->magnification);
cairo_translate (cr, -x, -y);
+ g_signal_handler_block (priv->inspected, priv->draw_handler);
gtk_widget_draw (priv->inspected, cr);
+ g_signal_handler_unblock (priv->inspected, priv->draw_handler);
cairo_restore (cr);
return TRUE;
}
+static void
+gtk_magnifier_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GtkMagnifier *magnifier;
+ GtkMagnifierPrivate *priv;
+ gint width;
+
+ magnifier = GTK_MAGNIFIER (widget);
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->resize && priv->inspected)
+ width = priv->magnification * gtk_widget_get_allocated_width (priv->inspected);
+ else
+ width = 0;
+
+ *minimum_width = width;
+ *natural_width = width;
+}
+
+static void
+gtk_magnifier_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GtkMagnifier *magnifier;
+ GtkMagnifierPrivate *priv;
+ gint height;
+
+ magnifier = GTK_MAGNIFIER (widget);
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->resize && priv->inspected)
+ height = priv->magnification * gtk_widget_get_allocated_height (priv->inspected);
+ else
+ height = 0;
+
+ *minimum_height = height;
+ *natural_height = height;
+}
+
+static void
+resize_handler (GtkWidget *widget,
+ GtkAllocation *alloc,
+ GtkWidget *magnifier)
+{
+ gtk_widget_queue_resize (magnifier);
+}
+
+static void
+connect_resize_handler (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->inspected && priv->resize)
+ priv->resize_handler = g_signal_connect (priv->inspected, "size-allocate",
+ G_CALLBACK (resize_handler), magnifier);
+}
+
+static void
+disconnect_resize_handler (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->resize_handler)
+ {
+ g_signal_handler_disconnect (priv->inspected, priv->resize_handler);
+ priv->resize_handler = 0;
+ }
+}
+
+static gboolean
+draw_handler (GtkWidget *widget,
+ cairo_t *cr,
+ GtkWidget *magnifier)
+{
+ gtk_widget_queue_draw (magnifier);
+ return FALSE;
+}
+
+static void
+connect_draw_handler (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->inspected)
+ priv->draw_handler = g_signal_connect (priv->inspected, "draw",
+ G_CALLBACK (draw_handler), magnifier);
+}
+
+static void
+disconnect_draw_handler (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->draw_handler)
+ {
+ g_signal_handler_disconnect (priv->inspected, priv->draw_handler);
+ priv->draw_handler = 0;
+ }
+}
+
+static void
+_gtk_magnifier_destroy (GtkWidget *widget)
+{
+ _gtk_magnifier_set_inspected (GTK_MAGNIFIER (widget), NULL);
+
+ GTK_WIDGET_CLASS (_gtk_magnifier_parent_class)->destroy (widget);
+}
+
static void
_gtk_magnifier_class_init (GtkMagnifierClass *klass)
{
object_class->set_property = _gtk_magnifier_set_property;
object_class->get_property = _gtk_magnifier_get_property;
+ widget_class->destroy = _gtk_magnifier_destroy;
widget_class->draw = _gtk_magnifier_draw;
+ widget_class->get_preferred_width = gtk_magnifier_get_preferred_width;
+ widget_class->get_preferred_height = gtk_magnifier_get_preferred_height;
g_object_class_install_property (object_class,
PROP_INSPECTED,
P_("magnification"),
1, G_MAXDOUBLE, 1,
G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_RESIZE,
+ g_param_spec_boolean ("resize",
+ P_("resize"),
+ P_("resize"),
+ FALSE,
+ G_PARAM_READWRITE));
}
static void
gtk_widget_set_has_window (widget, FALSE);
priv->magnification = 1;
+ priv->resize = FALSE;
}
GtkWidget *
if (priv->inspected == inspected)
return;
+ disconnect_draw_handler (magnifier);
+ disconnect_resize_handler (magnifier);
+
priv->inspected = inspected;
+
+ connect_draw_handler (magnifier);
+ connect_resize_handler (magnifier);
+
g_object_notify (G_OBJECT (magnifier), "inspected");
}
priv->magnification = magnification;
g_object_notify (G_OBJECT (magnifier), "magnification");
+ if (priv->resize)
+ gtk_widget_queue_resize (GTK_WIDGET (magnifier));
+
if (gtk_widget_is_visible (GTK_WIDGET (magnifier)))
gtk_widget_queue_draw (GTK_WIDGET (magnifier));
}
return priv->magnification;
}
+
+void
+_gtk_magnifier_set_resize (GtkMagnifier *magnifier,
+ gboolean resize)
+{
+ GtkMagnifierPrivate *priv;
+
+ g_return_if_fail (GTK_IS_MAGNIFIER (magnifier));
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->resize == resize)
+ return;
+
+ priv->resize = resize;
+
+ gtk_widget_queue_resize (GTK_WIDGET (magnifier));
+ if (resize)
+ connect_resize_handler (magnifier);
+ else
+ disconnect_resize_handler (magnifier);
+}
+
+gboolean
+_gtk_magnifier_get_resize (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_MAGNIFIER (magnifier), FALSE);
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ return priv->resize;
+}